﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpModelInterface.h"
#include "IExternalObject.h"
#include "OwnerPtr.h"
#include "IPlane.h"
#include "IPolygon.h"

namespace gcmp
{
    class IDocument;
    class IExternalDatas;
    struct CurveIndexInPolygon;

    /// \brief 遮罩区域，在指定闭合轮廓生成一块区域
    class GCMP_MODEL_INTERFACE_EXPORT IMaskingRegion : public IExternalObject
    {
        DEFINE_CAST_DERIVED(gcmp::IMaskingRegion, gcmp::IExternalObject)
    public:
        /// \brief 析构函数
        virtual ~IMaskingRegion() {}

        /// \brief 创建遮罩区域
        ///
        /// \param[in] pDocument 文档指针
        /// \param[in] modelViewId 遮罩区域所在视图的ElementId，在其他视图下不显示
        /// \param[in] opPlane 遮罩区域所在平面
        /// \param[in] opPolygon 遮罩区域轮廓
        /// \param[in] pMaskingRegionBoundaryCurveStyleMap 遮罩区域边界样式信息。为空则使用默认样式
        /// \return 如果成功，则返回遮罩区域的指针，如果失败，则为nullptr
        static IMaskingRegion* Create(
            IDocument *pDocument,
            const ElementId &modelViewId,
            OwnerPtr<IPlane> opPlane,
            OwnerPtr<IPolygon> opPolygon,
            const std::map<CurveIndexInPolygon, ElementId>* pMaskingRegionBoundaryCurveStyleMap = nullptr);

        /// \brief 设置遮罩区域所在平面，一个遮罩区域的三维几何表示由一个平面和一个二维多边形表示
        ///
        /// \param[in] opPlane 遮罩区域所在平面，不能为空
        virtual void SetPlane(OwnerPtr<IPlane> opPlane) = 0;

        /// \brief 获取遮罩区域所在平面，一个遮罩区域的三维几何表示由一个平面和一个二维多边形表示
        ///
        /// \return 遮罩区域所在平面，不能为空
        virtual const IPlane* GetPlane() const = 0;

        /// \brief 设置遮罩区域轮廓，一个遮罩区域的三维几何表示由一个平面和一个二维多边形表示
        ///
        /// \param[in] opPolygon 遮罩区域轮廓，不能为空
        virtual void SetBoundary(OwnerPtr<IPolygon> opPolygon) = 0;

        /// \brief 获取遮罩区域轮廓，一个遮罩区域的三维几何表示由一个平面和一个二维多边形表示
        ///
        /// \return 遮罩区域轮廓，不能为空
        virtual const IPolygon* GetBoundary() const = 0;

        /// \brief 设置所属视图的ElementId
        ///
        /// \param[in] viewId 所属视图的ElementId
        virtual void SetModelViewId(const ElementId &viewId) = 0;

        /// \brief 获取所属视图的ElementId
        ///
        /// \return 所属视图的ElementId
        virtual ElementId GetModelViewId() const = 0;

        /// \brief 获取当前遮罩区域边界线的可见性
        ///
        /// \return 可见返回true，不可见返回false
        virtual bool IsBorderVisible() const = 0;

        /// \brief 设置当前遮罩区域边界线的可见性
        ///
        /// \param bVisible 可见性
        virtual void SetIsBorderVisible(bool bVisible) = 0;

        /// \brief 设置当前遮罩区域边界线的样式
        ///
        /// \param curveIndex 曲线在多边形中的索引
        /// \return 设置成功返回true， 失败返回false
        virtual bool SetBoundaryStyle(const CurveIndexInPolygon &curveIndex, const ElementId& styleElementId) = 0;

        /// \brief 返回当前遮罩区域边界线的样式
        ///
        ///        如果一条边界线样式被重载过，那么返回重载过的样式，否则不返回该边界线的样式信息
        /// \return 遮罩区域边界线的样式
        virtual std::map<CurveIndexInPolygon, ElementId> GetBoundaryStyle() const = 0;
        
        /// \brief 得到遮罩区域关联更新变化Id
        ///
        ///  该变化不包含样式变化
        /// \return 遮罩区域关联更新变化Id
        virtual RegenDataId GetRegionChangedRdId() const = 0;

        /// \brief 获取遮罩区域的所有外部扩展数据
        ///
        /// \return 返回遮罩区域的所有外部扩展数据
        virtual const IExternalDatas* GetExternalDatas() const = 0;

        /// \brief 获取遮罩区域的所有外部扩展数据，用户可以通过此函数返回值对外部扩展数据进行修改
        ///
        /// \return 返回遮罩区域的所有外部扩展数据
        virtual IExternalDatas* GetExternalDatas() = 0;

        /// \brief 设置是否可以被选择
        /// 
        /// \param isSelectable true-可以被选择；false-不可以被选择
        /// \return true 设置成功，false设置失败
        virtual bool SetIsSelectable(bool isSelectable) = 0;

        /// \brief 获取是否可以被选择
        /// 
        /// \return true-可以被选择；false-不可以被选择
        virtual bool IsSelectable() const = 0;

        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();
    };

}
